﻿using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using EnvDTE;
using EnvDTE80;
using Microsoft.VisualStudio.CommandBars;
using stdole;
using System.Resources;

namespace DotNetDalAddin.CodeHelper
{
    public class IconUtils
    {

        public static Command AddCommandWithicon(Commands2 root,
            CommandBarPopup menuToAddTo,
            string name,
            string buttonText,
            string buttonDescription,
            Bitmap iconFile,
            AddIn addInInstance)
        {

            object[] contextGUIDS = null;

            Command command = root.AddNamedCommand2(addInInstance,
                                                        name,
                                                        buttonText,
                                                        buttonDescription,
                                                        true, 59,
                                                        ref contextGUIDS,
                                                        (int)vsCommandStatus.vsCommandStatusSupported +
                                                        (int)vsCommandStatus.vsCommandStatusEnabled,
                                                        (int)vsCommandStyle.vsCommandStylePictAndText,
                                                        vsCommandControlType.vsCommandControlTypeButton);

            CommandBarButton control = (CommandBarButton)command.AddControl(menuToAddTo.CommandBar, 1);

            SetControlPicture(control, iconFile);

            return command;
        }

        private static Color guessTransparentColor(Bitmap bitmap)
        {
            Color pixel = bitmap.GetPixel(0, 0);
            Color color2 = bitmap.GetPixel(bitmap.Width - 1, 0);
            Color color3 = bitmap.GetPixel(0, bitmap.Height - 1);
            Color color4 = bitmap.GetPixel(bitmap.Width - 1, bitmap.Height - 1);

            if (pixel == color2)
            {
                return pixel;
            }

            if (color2 == color3)
            {
                return color2;
            }

            if (color3 == color4)
            {
                return color3;
            }

            return color4;

        }

        protected static Bitmap PrepareImage(Image image, Color transparentColor)
        {

            Bitmap bitmap = new Bitmap(image);
            Bitmap bitmap2 = new Bitmap(0x10, 0x10, PixelFormat.Format24bppRgb);
            Color color = guessTransparentColor(bitmap);

            for (int i = 0; i < bitmap2.Width; i++)
            {
                for (int j = 0; j < bitmap2.Height; j++)
                {
                    Color baseColor = color;

                    if ((i < bitmap.Width) && (j < bitmap.Height))
                    {
                        baseColor = bitmap.GetPixel(i, j);
                    }

                    baseColor = Color.FromArgb(0xff, baseColor);

                    if (baseColor != color)
                    {
                        bitmap2.SetPixel(i, j, baseColor);
                    }
                    else if ((transparentColor != color) && (baseColor == transparentColor))
                    {
                        if (baseColor.R > 0)
                        {
                            bitmap2.SetPixel(i, j, Color.FromArgb(baseColor.R - 1, baseColor.G, baseColor.B));
                        }
                        else
                        {
                            bitmap2.SetPixel(i, j, Color.FromArgb(baseColor.R + 1, baseColor.G, baseColor.B));
                        }
                    }
                    else
                    {
                        bitmap2.SetPixel(i, j, transparentColor);
                    }

                }
            }

            return bitmap2;
        }

        protected static Bitmap PrepareMask(Image image)
        {
            Bitmap bitmap = new Bitmap(image);
            Bitmap bitmap2 = new Bitmap(0x10, 0x10, PixelFormat.Format24bppRgb);

            Color color = guessTransparentColor(bitmap);

            for (int i = 0; i < image.Width; i++)
            {
                for (int j = 0; j < image.Height; j++)
                {
                    Color pixel = bitmap.GetPixel(i, j);
                    Color color3 = ((pixel == color) || (pixel.A < 0xff)) ? Color.White : Color.Black;

                    bitmap2.SetPixel(i, j, color3);
                }
            }

            return bitmap2;
        }

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
        private struct SHFILEINFO
        {

            public IntPtr hIcon;
            public int iIcon;
            public int dwAttributes;

            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x100)]
            public char[] szDisplayName;

            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 80)]
            public char[] szTypeName;
        }

        protected static Icon GetIconFromFile(string path)
        {
            SHFILEINFO psfi = new SHFILEINFO();
            SHGetFileInfo(path, 0x80, ref psfi, Marshal.SizeOf(psfi), 0x111);
            return Icon.FromHandle(psfi.hIcon);
        }

        [DllImport("shell32.dll", CharSet = CharSet.Auto)]
        private static extern IntPtr SHGetFileInfo(string pszPath, int dwFileAttributes, ref SHFILEINFO psfi, int cbFileInfo, int uFlags);

        [DllImport("oleaut32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        internal static extern int OleLoadPictureFile(object fileName, [MarshalAs(UnmanagedType.IDispatch)] ref object iPictureDisp);
        static Color VS_MENUCOLOR = Color.FromArgb(0xec, 0xe9, 0xd8);

        public static void SetControlPicture(CommandBarButton button, Bitmap picture)
        {
            //Image image1 = GetImageFromAnyFormat(fileName);
            Bitmap image2 = PrepareImage(picture, VS_MENUCOLOR);
            Bitmap image3 = PrepareMask(image2);

            button.Picture = CreatePictureDisp(image2);
        }

        protected static Image GetImageFromAnyFormat(string path)
        {
            string str = path.ToLower();

            if (str.EndsWith(".exe") || str.EndsWith(".ico"))
            {
                return GetIconFromFile(path).ToBitmap();
            }

            return Image.FromFile(path, true);
        }

        protected static object OleLoadPictureFile(string fileName)
        {
            object iPictureDisp = null;
            OleLoadPictureFile(fileName, ref iPictureDisp);

            return iPictureDisp;
        }

        protected static StdPicture CreatePictureDisp(Image image)
        {
            return (StdPicture)ImageConverter.GetIPictureDispFromImage(image);
        }
    }

    class ImageConverter : AxHost
    {
        // Methods
        internal ImageConverter()
            : base("52D64AAC-29C1-CAC8-BB3A-115F0D3D77CB")
        {

        }

        public static IPictureDisp GetIPictureDispFromImage(Image image)
        {

            return (IPictureDisp)AxHost.GetIPictureDispFromPicture(image);

        }
    }
}